OutlineCore.hlsl 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #ifndef FLAT_KIT_OUTLINE_INCLUDED
  2. #define FLAT_KIT_OUTLINE_INCLUDED
  3. TEXTURE2D_X (_BlitTexture);
  4. SAMPLER (sampler_BlitTexture);
  5. float Linear01Depth(float z)
  6. {
  7. const float isOrtho = unity_OrthoParams.w;
  8. const float isPers = 1.0 - unity_OrthoParams.w;
  9. z *= _ZBufferParams.x;
  10. return (1.0 - isOrtho * z) / (isPers * z + _ZBufferParams.y);
  11. }
  12. float SampleDepth(float2 uv)
  13. {
  14. const float d = SampleSceneDepth(uv);
  15. return Linear01Depth(d);
  16. }
  17. float4 SampleCameraColor(float2 uv)
  18. {
  19. return SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_BlitTexture, UnityStereoTransformScreenSpaceTex(uv));
  20. }
  21. void Outline_float(float2 UV, out float4 Out)
  22. {
  23. float4 original = SampleCameraColor(UV);
  24. const float offset_positive = +ceil(_Thickness * 0.5f);
  25. const float offset_negative = -floor(_Thickness * 0.5f);
  26. #if RESOLUTION_INVARIANT_THICKNESS
  27. const float screen_ratio = _ScreenSize.x / _ScreenSize.y;
  28. const float2 texel_size = 1.0 / 800.0 * float2(1.0, screen_ratio);
  29. #else
  30. const float2 texel_size = _ScreenSize.zw;
  31. #endif
  32. float left = texel_size.x * offset_negative;
  33. float right = texel_size.x * offset_positive;
  34. float top = texel_size.y * offset_negative;
  35. float bottom = texel_size.y * offset_positive;
  36. const float2 uv0 = UV + float2(left, top);
  37. const float2 uv1 = UV + float2(right, bottom);
  38. const float2 uv2 = UV + float2(right, top);
  39. const float2 uv3 = UV + float2(left, bottom);
  40. #ifdef OUTLINE_USE_DEPTH
  41. const float d0 = SampleDepth(uv0);
  42. const float d1 = SampleDepth(uv1);
  43. const float d2 = SampleDepth(uv2);
  44. const float d3 = SampleDepth(uv3);
  45. const float depth_threshold_scale = 300.0f;
  46. float d = length(float2(d1 - d0, d3 - d2)) * depth_threshold_scale;
  47. d = smoothstep(_DepthThresholdMin, _DepthThresholdMax, d);
  48. #else
  49. float d = 0.0f;
  50. #endif // OUTLINE_USE_DEPTH
  51. #ifdef OUTLINE_USE_NORMALS
  52. const float3 n0 = SampleSceneNormals(uv0);
  53. const float3 n1 = SampleSceneNormals(uv1);
  54. const float3 n2 = SampleSceneNormals(uv2);
  55. const float3 n3 = SampleSceneNormals(uv3);
  56. const float3 nd1 = n1 - n0;
  57. const float3 nd2 = n3 - n2;
  58. float n = sqrt(dot(nd1, nd1) + dot(nd2, nd2));
  59. n = smoothstep(_NormalThresholdMin, _NormalThresholdMax, n);
  60. #else
  61. float n = 0.0f;
  62. #endif // OUTLINE_USE_NORMALS
  63. #ifdef OUTLINE_USE_COLOR
  64. const float3 c0 = SampleCameraColor(uv0).rgb;
  65. const float3 c1 = SampleCameraColor(uv1).rgb;
  66. const float3 c2 = SampleCameraColor(uv2).rgb;
  67. const float3 c3 = SampleCameraColor(uv3).rgb;
  68. const float3 cd1 = c1 - c0;
  69. const float3 cd2 = c3 - c2;
  70. float c = sqrt(dot(cd1, cd1) + dot(cd2, cd2));
  71. c = smoothstep(_ColorThresholdMin, _ColorThresholdMax, c);
  72. #else
  73. float c = 0;
  74. #endif // OUTLINE_USE_COLOR
  75. const float g = max(d, max(n, c));
  76. #ifdef OUTLINE_FADE_OUT
  77. const float linear_depth = LinearEyeDepth(SampleSceneDepth(UV), _ZBufferParams);
  78. const float fade = smoothstep(_FadeRangeEnd, _FadeRangeStart, linear_depth);
  79. _EdgeColor.a *= fade;
  80. #endif // OUTLINE_FADE_OUT
  81. #ifdef OUTLINE_ONLY
  82. original.rgb = lerp(1.0 - _EdgeColor.rgb, _EdgeColor.rgb, g * _EdgeColor.a);
  83. #endif // OUTLINE_ONLY
  84. float4 output;
  85. output.rgb = lerp(original.rgb, _EdgeColor.rgb, g * _EdgeColor.a);
  86. output.a = original.a;
  87. Out = output;
  88. }
  89. #endif // FLAT_KIT_OUTLINE_INCLUDED